using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;

public class TilemapPathGenerator : MonoBehaviour
{
    public PathSize pathSize = PathSize.Medium; // 路径尺寸（小/中/大）
    public Tilemap tilemap;                     // 用于绘制的瓦片地图
    public TileBase pathTile;                   // 路径瓦片类型
    public TileBase startTile;                  // 起点瓦片类型
    
    private void OnEnable() {
        EventHandler.AfterSceneLoadEvent += OnAfterSceneLoadEvent;
    }


    private void OnDisable() {
        EventHandler.AfterSceneLoadEvent -= OnAfterSceneLoadEvent;
    }



    private void OnAfterSceneLoadEvent()
    {
        tilemap = GameObject.FindWithTag("GroundMiddle").GetComponent<Tilemap>();
        GeneratePath(); 
    }

    // 定义不同尺寸对应的地图尺寸（宽高）
    private Dictionary<PathSize, Vector2Int> sizeMap = new Dictionary<PathSize, Vector2Int>()
    {
        { PathSize.Small, new Vector2Int(10, 7) },   // 小尺寸：10x7
        { PathSize.Medium, new Vector2Int(15, 10) }, // 中尺寸：15x10
        { PathSize.Large, new Vector2Int(20, 14) }   // 大尺寸：20x14
    };
    
    private List<Vector3Int> generatedPath = new List<Vector3Int>(); // 存储已生成路径的坐标

    // 主路径生成方法
    public void GeneratePath()
    {
        tilemap.ClearAllTiles();   // 清空所有已有瓦片
        generatedPath.Clear();     // 重置路径记录

        // 获取当前尺寸设置对应的地图尺寸
        Vector2Int size = sizeMap[pathSize];
        int halfWidth = size.x / 2;   // 计算半宽（用于中心对称布局）
        int halfHeight = size.y / 2;  // 计算半高

        // 设置起点（固定于右上角）
        Vector3Int pathStart = new Vector3Int(halfWidth, halfHeight, 0);
        AddTile(pathStart, startTile); // 添加起点瓦片

        // 1. 生成右边线（从上到下）
        Vector3Int rightEnd = new Vector3Int(halfWidth, -halfHeight, 0);
        Vector3Int actualRightEnd = GenerateEdge(
            pathStart,
            rightEnd,
            false,                   // 垂直方向移动（非水平）
            out Vector3Int lastAddedRight
        );

        // 处理右边线终点可能的重叠情况
        Vector3Int nextEdgeStartRight = actualRightEnd;
        if (generatedPath.Count >= 2)
        {
            Vector3Int secondLast = generatedPath[generatedPath.Count - 2];
            // 如果终点与前一位置形成直线
            if (actualRightEnd.y == secondLast.y && actualRightEnd.x > secondLast.x)
            {
                tilemap.SetTile(actualRightEnd, null); // 删除该终点瓦片
                generatedPath.Remove(actualRightEnd);  // 从路径中移除
                nextEdgeStartRight = secondLast;        // 新的连接起点设为前一位置
            }
        }

        // 2. 生成下边线（从右到左）
        Vector3Int bottomEnd = new Vector3Int(-halfWidth, nextEdgeStartRight.y, 0);
        Vector3Int actualBottomEnd = GenerateEdge(
            nextEdgeStartRight,
            bottomEnd,
            true,                    // 水平方向移动
            out Vector3Int lastAddedBottom
        );

        // 处理下边线终点可能的重叠情况
        Vector3Int nextEdgeStartBottom = actualBottomEnd;
        if (generatedPath.Count >= 2)
        {
            Vector3Int secondLast = generatedPath[generatedPath.Count - 2];
            // 如果终点与前一位置形成直线
            if (actualBottomEnd.x == secondLast.x && actualBottomEnd.y < secondLast.y)
            {
                tilemap.SetTile(actualBottomEnd, null);
                generatedPath.Remove(actualBottomEnd);
                nextEdgeStartBottom = secondLast;
            }
        }

        // 3. 生成左边线（从下到上）
        Vector3Int leftEnd = new Vector3Int(nextEdgeStartBottom.x, halfHeight, 0);
        Vector3Int actualLeftEnd = GenerateEdge(
            nextEdgeStartBottom,
            leftEnd,
            false,                   // 垂直方向移动
            out Vector3Int lastAddedLeft
        );

        // 处理左边线终点可能的重叠情况
        Vector3Int nextEdgeStartLeft = actualLeftEnd;
        if (generatedPath.Count >= 2)
        {
            Vector3Int secondLast = generatedPath[generatedPath.Count - 2];
            // 如果终点与前一位置形成直线
            if (actualLeftEnd.y == secondLast.y && actualLeftEnd.x < secondLast.x)
            {
                tilemap.SetTile(actualLeftEnd, null);
                generatedPath.Remove(actualLeftEnd);
                nextEdgeStartLeft = secondLast;
            }
        }

        // 4. 生成上边线（从左到右，回到起点）
        Vector3Int actualTopEnd = GenerateEdge(
            nextEdgeStartLeft,
            pathStart,
            true,                    // 水平方向移动
            out Vector3Int lastAddedTop
        );

        // 处理终点与起点重叠情况
        if (generatedPath.Count >= 2)
        {
            Vector3Int secondLast = generatedPath[generatedPath.Count - 2];
            // 如果起点与前一位置形成直线
            if (pathStart.x == secondLast.x && pathStart.y > secondLast.y)
            {
                tilemap.SetTile(pathStart, null);    // 移除原始起点
                generatedPath.Remove(pathStart);
                tilemap.SetTile(secondLast, startTile); // 将前一位置设为新起点
            }
        }
        EventHandler.CallFinishFollowingPath();
        
        EventHandler.CallStartFollowingPath(generatedPath, tilemap);
    }
    
    /// <summary>
    /// 生成单边路径的核心方法
    /// </summary>
    /// <param name="start">起始坐标</param>
    /// <param name="end">目标坐标</param>
    /// <param name="isHorizontal">移动方向是否为水平</param>
    /// <param name="lastAddedTile">输出最后添加的瓦片位置</param>
    /// <returns>实际结束位置</returns>
    private Vector3Int GenerateEdge(Vector3Int start, Vector3Int end, bool isHorizontal, out Vector3Int lastAddedTile)
    {
        lastAddedTile = start; // 初始化最后添加位置
        Vector3Int current = start; // 当前处理位置

        // 计算移动方向（X/Y方向上的增量）
        int xDir = end.x > start.x ? 1 : (end.x < start.x ? -1 : 0);
        int yDir = end.y > start.y ? 1 : (end.y < start.y ? -1 : 0);

        // 随机路径生成参数
        int lastShiftDirection = 0;  // 上次的偏移方向（0=未偏移，1=正向，-1=负向）
        int stepsSinceLastShift = 0; // 自上次偏移后经过的步数
        int shiftInterval = Random.Range(3, 6); // 下次偏移的间隔步数（3-5步）
        
        const int CORNER_PROTECTION_RANGE = 2; // 拐角保护范围（接近终点时不偏移）

        // 路径生成主循环
        while (current != end)
        {
            Vector3Int next = current;
            bool shiftOccurred = false; // 标记本次是否发生偏移

            // 计算当前到终点的剩余步数
            int remainingSteps = isHorizontal ? 
                Mathf.Abs(current.x - end.x) : 
                Mathf.Abs(current.y - end.y);

            bool canShift = remainingSteps > CORNER_PROTECTION_RANGE; // 确定当前能否偏移

            // 偏移逻辑：达到间隔步数且可以偏移
            if (stepsSinceLastShift >= shiftInterval && canShift)
            {
                int shiftDir = 0;
                
                if (lastShiftDirection == 0) 
                {
                    // 首次偏移：随机选择方向
                    shiftDir = Random.Range(0, 2) == 0 ? 1 : -1;
                    lastShiftDirection = shiftDir;
                }
                else 
                {
                    // 后续偏移：必须与上次方向相反
                    shiftDir = -lastShiftDirection;
                    lastShiftDirection = shiftDir;
                }

                // 根据移动方向应用偏移
                if (isHorizontal) next.y += shiftDir;
                else next.x += shiftDir;
                
                shiftOccurred = true; // 标记发生偏移
            }
            else
            {
                // 正常直线移动
                if (isHorizontal) next.x += xDir;
                else next.y += yDir;
            }

            // 边界保护：防止越过终点
            if ((isHorizontal && Mathf.Abs(next.x - end.x) > Mathf.Abs(current.x - end.x)) ||
                (!isHorizontal && Mathf.Abs(next.y - end.y) > Mathf.Abs(current.y - end.y)))
            {
                next = end; // 直接跳到终点
            }

            if (next != current)
            {
                AddTile(next, pathTile);  // 添加路径瓦片
                lastAddedTile = next;     // 更新最后添加位置
                current = next;           // 移动到新位置
                
                // 更新偏移计数器
                if (shiftOccurred)
                {
                    stepsSinceLastShift = 0;           // 重置步数计数
                    shiftInterval = Random.Range(3, 6); // 重新设置随机间隔
                }
                else
                {
                    stepsSinceLastShift++; // 增加步数计数
                }
            }
            else if (next == end)
            {
                current = next; // 直接设为终点（安全防护）
            }
        }
        
        return current; // 返回实际结束位置
    }
    
    /// <summary>
    /// 安全添加瓦片（避免重复添加）
    /// </summary>
    private void AddTile(Vector3Int position, TileBase currentTile)
    {
        if (!generatedPath.Contains(position)) 
        {
            tilemap.SetTile(position, currentTile);
            generatedPath.Add(position); // 记录已生成位置
        }
    }
    
    // 获取生成的路径坐标列表
    public List<Vector3Int> GetGeneratedPath()
    {
        return generatedPath;
    }
}